namespace GYLite
{
						
				
	/**DraggerHandle类是一个简易的拖动类，快速创建一个拖动响应的操作
	 * 绑定对象，当对象触发MOUSE_DOWN事件，就提供一个帧频调用的回调函数，使用s.addBind添加拖动的响应函数
	 * */
	export class DraggerHandle
	{
		private _bindList:Function[];
		private _bindObjList:any[];
		private _handle:IGYDisplay;
		private _dragTarget:any;
		private _dropTarget:any;
		private _dragMouseX:number;
		private _dragMouseY:number;
		private _touchId:number;
		private _updateFunc:Function;
		private _updateObj:any;
		private _stopTouchEvent:boolean;
		private _longTapTime:number;
		private _longTapId:number;
		private _dragState:number;
		private _isDragMove:boolean;
		private _isRightMouse:boolean;
		private _touchBeginEvent:string;
		private _touchEndEvent:string;
		private _touchMoveEvent:string;
		private _tapEvent:string;
		/**是否其他手指抬起是否不判断其id，如果为true，则不判断id，其他手指id的触碰抬起也会触发结束拖拽，默认true*/public ignoreOtherTouch:boolean;
		public constructor()
		{
			let s = this;
			s._longTapTime = -1;
			s._longTapId = -1;
			s._stopTouchEvent = s.ignoreOtherTouch = true;
			s.setRightMouseDrag(false);
		}
		/**设置是否右键拖拽*/
		public setRightMouseDrag(val:boolean):void
		{
			let s= this;
			if(s._isRightMouse == val)return;
			s._isRightMouse = val;			
			if(s._handle)
			{
				s._handle.removeEventListener(s._touchBeginEvent, s.startDragFunc, s);
				s._handle.removeEventListener(s._touchEndEvent, s.stopDragFunc, s);				
				s._handle.removeEventListener(s._tapEvent, s.tap, s);
				GYSprite.stage.removeEventListener(s._touchMoveEvent,s.touchMove,s);
			}
			

			s._touchBeginEvent = val?egret.TouchEvent.RIGHT_BEGIN:egret.TouchEvent.TOUCH_BEGIN;
			s._touchEndEvent = val?egret.TouchEvent.RIGHT_END:egret.TouchEvent.TOUCH_END;
			s._touchMoveEvent = val?egret.TouchEvent.RIGHT_TOUCH_MOVE:egret.TouchEvent.TOUCH_MOVE;
			s._tapEvent = val?egret.TouchEvent.RIGHT_TAP:egret.TouchEvent.TOUCH_TAP;

			if(s._handle)
			{
				s._handle.addEventListener(s._touchBeginEvent, s.startDragFunc, s);
				s._handle.addEventListener(s._tapEvent, s.tap, s);
			}
		}
		/**当前响应的触碰id*/
		public get touchId():number
		{
			return this._touchId;
		}
		/*拖拽的状态 0 初始化 1 按下 2 移动 3 松开 **/
		public get dragState():number
		{
			return this._dragState;
		}
		public set longTapTime(val:number)
		{
			let s = this;
			s._longTapTime = val;
		}
		/**长按响应*/
		public get longTapTime():number
		{
			let s = this;
			return s._longTapTime;
		}
		/**长按延时id -1代表没有长按触发*/
		public get longTapId():number
		{
			return this._longTapId;
		}
		/**当拖拽产生时，是否屏蔽鼠标点击事件(默认true)*/
		public whenDragStopTouch(val:boolean)
		{
			let s = this;
			s._stopTouchEvent = val;
		}
		//拖动鼠标形态0 默认 1拉伸 public dragType:number;
		private touchMove(e:egret.TouchEvent):void
		{
			let s = this;
			if(s._longTapId > -1)
			{				
				GYLite.TimeManager.unTimeOut(s._longTapId,s.doStartDrag,s);
				s._longTapId = -1;
				s.stopDrag();
				return;
			}
			if(s._touchId == e.touchPointID)
			{
				s._dragState = 2;
				s._isDragMove = true;
				s.draggingLoop(CommonUtil.loopTime);
			}
				
		}
		private draggingLoop(t:number):void
		{var s = this;
			var len:number = s._bindList.length;
			while(--len> -1)
				s._bindList[len].call(s._bindObjList[len],this);
		}
		private rollOver(e:GYLite.MouseEvent):void
		{
			let s = this;
			if(s._stopTouchEvent && s._isDragMove)
				e.stopImmediatePropagation();
		}
		private rollOut(e:GYLite.MouseEvent):void
		{
			let s = this;
			if(s._stopTouchEvent && s._isDragMove)
				e.stopImmediatePropagation();
		}
		private tap(e:egret.TouchEvent):void
		{
			let s = this;
			if(s._stopTouchEvent && s._isDragMove)
				e.stopImmediatePropagation();
		}
		private startDragFunc(e:egret.TouchEvent):void
		{var s = this;
			if(s._bindList == null)return;	
			if(s._dragTarget)return;
			s._dragTarget = e.target;
			s._touchId = e.touchPointID;
			if(s._longTapId > -1)
			{				
				GYLite.TimeManager.unTimeOut(s._longTapId,s.doStartDrag,s);
				s._longTapId = -1;
			}
			if(s._longTapTime > -1)
				s._longTapId = GYLite.TimeManager.timeOut(s.doStartDrag,s,s._longTapTime);
			s.startDrag(s._dragTarget, s.ignoreOtherTouch?NaN:e.touchPointID, true);			
		}
		private doStartDrag():void
		{
			let s = this;
			s._longTapId = -1;
			if(s._handle.hasEventListener(GYViewEvent.DRAGSTART))
				s._handle.dispatchEvent(new GYViewEvent(GYViewEvent.DRAGSTART,false,false,s));	
		}
		/**帧频刷新回调
		 * @param func 回调函数 (d:DraggerHandler)=>void
		 * @param obj this指向
		*/
		public setUpdateFunc(func:Function,obj:any):void
		{
			let s = this;
			s._updateFunc = func;
			s._updateObj = obj;
		}
		private frameLoop(t:number):void
		{
			let s =this;
			if(s._updateFunc!=null)
				s._updateFunc.call(s._updateObj,s);
		}
		private stopDragFunc(e:egret.TouchEvent):void
		{var s = this;
			// Mouse.cursor = MouseCursor.AUTO;
			var e2:GYTouchEvent = e as GYTouchEvent;
			if(e2)
			{
				s._dropTarget = e2.outsideTarget;
				if(s._touchId != e2.touchPointID && !s.ignoreOtherTouch)
					return;
			}				
			else
				s._dropTarget = null;
			s.stopDrag();
			if(s._handle && s._handle.hasEventListener(GYViewEvent.DRAGSTOP))
				s._handle.dispatchEvent(new GYViewEvent(GYViewEvent.DRAGSTOP,false,false,s));
			if(s._stopTouchEvent && s._isDragMove)
				e.stopImmediatePropagation();
			s._isDragMove = false;
		}
		public stopDrag():void
		{
			let s = this;
			s._dragState = 3;
			CommonUtil.delStageLoop(s.frameLoop,s);
			GYSprite.stage.removeEventListener(s._touchMoveEvent,s.touchMove,s);
			if(s._handle)			
			{
				GYSprite.removeStageDown(s.handle,s.stopDragFunc, s);
				s._handle.removeEventListener(s._touchEndEvent, s.stopDragFunc, s);
			}
			s._dragTarget = null;			
		}
		public startDrag(target:Object,touchId:number=NaN, event:boolean=false):void
		{var s = this;			
			s._dragMouseX = (<GYSprite>s._handle.parent).mouseX - s._handle.x;
			s._dragMouseY = (<GYSprite>s._handle.parent).mouseY - s._handle.y;
			s._dragTarget = target;
			CommonUtil.addStageLoop(s.frameLoop,s);
			GYSprite.stage.addEventListener(s._touchMoveEvent,s.touchMove,s);
			GYSprite.addStageDown(s.handle,s.stopDragFunc, s, false, touchId);
			s._handle.addEventListener(s._touchEndEvent, s.stopDragFunc, s);
			s._dragState = 1;
			s._isDragMove = false;
			if(touchId == touchId)
				s._touchId = touchId;
			if(event)
			{
				if(s._handle.hasEventListener(GYViewEvent.DRAGSTART))
					s._handle.dispatchEvent(new GYViewEvent(GYViewEvent.DRAGSTART,false,false,s));		
			}
			s.draggingLoop(CommonUtil.loopTime);
		}
		
		/**添加s.handle拖动的绑定，拖动时回调binder函数来通知
		 * @param binder(drager:DraggerHandle):void回调函数
		 * */
		public addBind(binder:Function, thisObject:any):void
		{var s = this;
			if(binder == null)
				return;
			if(s._bindList == null)
			{
				s._bindList = new Array<Function>();
				s._bindObjList = [];
			}							
			var ind:number = s._bindList.indexOf(binder);
			if(ind == -1 || s._bindObjList[ind] != thisObject)
			{
				s._bindList.push(binder);	
				s._bindObjList.push(thisObject);	
			}				
		}
		/**清除s.handle拖动的绑定*/
		public delBind(binder:Function, thisObject:any):void
		{var s = this;
			if(s._bindList == null)return;			
			var len:number;
			len = s._bindList.length;
			while(--len>-1)
			{
				if(s._bindList[len] ==binder && s._bindObjList[len] == thisObject)
				{
					s._bindList.splice(len, 1);
					s._bindObjList.splice(len, 1);
				}
			}
		}
		
		/**启动拖动*/
		public run(gySp:IGYDisplay):void
		{var s = this;
			if(s._handle == gySp)
				return;
			s._dragState = 0;
			s._isDragMove = false;
			s._handle = gySp;
			s._handle.addEventListener(s._touchBeginEvent, s.startDragFunc, s);
			s._handle.addEventListener(s._tapEvent, s.tap, s);			
			s._handle.addEventListener(GYLite.MouseEvent.ROLL_OVER, s.rollOver, s);
			s._handle.addEventListener(GYLite.MouseEvent.ROLL_OUT, s.rollOut, s);
		}
		/**清除s.handle的拖动*/
		public clear():void
		{var s = this;
			if(s._bindList)s._bindList.length = 0;
			if(s._bindObjList)s._bindObjList.length = 0;
			if(s._longTapId > -1)
			{
				GYLite.TimeManager.unTimeOut(s._longTapId,s.doStartDrag,s);
				s._longTapId = -1;
			}
			s._handle.removeEventListener(s._touchBeginEvent, s.startDragFunc, s);
			s._handle.removeEventListener(s._touchEndEvent, s.stopDragFunc, s);
			s._handle.removeEventListener(s._tapEvent, s.tap, s);
			GYSprite.stage.removeEventListener(s._touchMoveEvent,s.touchMove,s);
			s._handle.removeEventListener(GYLite.MouseEvent.ROLL_OVER, s.rollOver, s);
			s._handle.removeEventListener(GYLite.MouseEvent.ROLL_OUT, s.rollOut, s);			
			CommonUtil.delStageLoop(s.frameLoop,s);
			s._dragTarget = s._handle = null;
			s._stopTouchEvent = false;
			s._touchId = NaN;
			s.setUpdateFunc(null,null);
			s.setRightMouseDrag(false);
		}
		/**被点击绑定的GYSprite*/
		public get handle():IGYDisplay
		{var s = this;
			return s._handle;
		}
		/**被拖动的DisplayObject*/
		public get dragTarget():any
		{var s = this;
			return s._dragTarget;
		}
		/**被放置的DisplayObject*/
		public get dropTarget():any
		{var s = this;
			return s._dropTarget;
		}
		/**拖动开启时，s.handle的mouseX*/
		public get dragMouseX():number
		{var s = this;
			return s._dragMouseX;
		}
		/**拖动开启时，s.handle的mouseY*/
		public get dragMouseY():number
		{var s = this;
			return s._dragMouseY;
		}
		/**设置对象可拖拽*/
		public static dragSet(sprite:GYLite.GYSprite, enabled:boolean=true):DraggerHandle
		{
			let handler:DraggerHandle;
			handler = DraggerHandle.getInstance(sprite);
			if(enabled)
			{
				if(!sprite.dragEnabled)
					handler.addBind(DraggerHandle.dragLoop, sprite);
				return handler;
			}
			else
			{
				if(sprite.dragEnabled)
					handler.clear();
				return null;
			}
			
		}
		private static dragLoop(d:DraggerHandle):void
		{
			let pr:GYLite.GYSprite = <GYLite.GYSprite>d.handle.parent;
            let s = <GYLite.GYSprite><any>this;
			s.x = pr.mouseX + (s.dragOffsetX == s.dragOffsetX?s.dragOffsetX:-d.dragMouseX);
			s.y = pr.mouseY + (s.dragOffsetY == s.dragOffsetY?s.dragOffsetY:-d.dragMouseY);            
		}
		
		private static handleVec:DraggerHandle[]=new Array<DraggerHandle>();
		/**获取拖动监听实例*/
		public static getInstance(gySp:IGYDisplay):DraggerHandle
		{
			var len:number;
			var waitHandle:DraggerHandle,handle:DraggerHandle;
			len = DraggerHandle.handleVec.length;
			while(--len>-1)
			{
				handle = DraggerHandle.handleVec[len];
				if(handle.handle)
				{
					if(handle.handle == gySp)
						return handle;
				}
				else if(waitHandle == null)
					waitHandle = handle;
			}
			if(waitHandle)
			{
				waitHandle.run(gySp);
				return waitHandle;
			}
			handle = new DraggerHandle;
			handle.run(gySp);
			DraggerHandle.handleVec.push(handle);
			return handle;
		}
		/**对被销毁的对象的DraggerHandle进行垃圾回收*/
		public static gc():void
		{
			let len:number;
			let handle:IGYDisplay;
			len = DraggerHandle.handleVec.length;
			while(--len > -1)
			{
				handle = DraggerHandle.handleVec[len].handle;
				if(handle && handle.disposed)
				{
					DraggerHandle.handleVec[len].clear();
					DraggerHandle.handleVec.splice(len,1);
				}
			}
		}
	}
}